/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop;

/**
 * Core Spring pointcut abstraction.
 *
 * <p>A pointcut is composed of a {@link ClassFilter} and a {@link MethodMatcher}.
 * Both these basic terms and a Pointcut itself can be combined to build up combinations
 * (e.g. through {@link org.springframework.aop.support.ComposablePointcut}).
 *
 * @author Rod Johnson
 * @see ClassFilter
 * @see MethodMatcher
 * @see org.springframework.aop.support.Pointcuts
 * @see org.springframework.aop.support.ClassFilters
 * @see org.springframework.aop.support.MethodMatchers
 */
/*
1. 总结
Pointcut 是 Spring AOP 中的核心抽象接口，用于定义切面的切入点。
它由 ClassFilter 和 MethodMatcher 组成，分别控制类和方法的匹配规则。
提供了静态常量 TRUE 表示始终匹配的点切。

2. 内部成员解释
getClassFilter() 返回该点切所使用的 ClassFilter，用于判断目标类是否符合切入点条件。
getMethodMatcher() 返回该点切所使用的 MethodMatcher，用于判断目标方法是否符合切入点条件。
TRUE 静态常量，表示一个总是匹配的 Pointcut 实例，即对所有类和方法都生效。

3. 相关的接口和类
Pointcut	用于定义切入点（即哪些类和方法需要被增强）（getClassFilter和getMethodMatcher）
├── ExpressionPointcut	支持基于表达式的切入点匹配（如 AspectJ 表达式）。
│   └── AbstractExpressionPointcut
│       └── AspectJExpressionPointcut	支持 execution(* com.example.service.*.*(..)) 等语法。
├── DynamicMethodMatcherPointcut	允许在运行时动态判断方法是否匹配。
├── AnnotationMatchingPointcut	匹配带有特定注解的方法或类。
├── ControlFlowPointcut	基于控制流（call stack）来决定是否触发增强，检查当前调用栈中是否有指定类/方法的调用。（案例：只在某些业务流程中启用 AOP 功能。）
├── TruePointcut	一个“万能”点切，总是返回 true，表示匹配所有类和方法。
├── ComposablePointcut	可组合多个 Pointcut 实例，形成复杂的逻辑组合（如 and, or, not）
└── StaticMethodMatcherPointcut		基于静态分析（无需运行时上下文）判断方法是否匹配。
     ├── AbstractRegexpMethodPointcut
     │   └── JdkRegexpMethodPointcut	使用 Java 正则表达式匹配方法名。
     ├── CacheOperationSourcePointcut	匹配带有 @Cacheable, @CacheEvict 等缓存注解的方法。
     ├── TransactionAttributeSourcePointcut	匹配带有 @Transactional 注解的方法。
     ├── NameMatchMethodPointcut	按照方法名称精确匹配。
     ├── StaticMethodMatcherPointcutAdvisor	封装了 StaticMethodMatcherPointcut 和 Advice，是一个完整的增强器。
     │   ├── TestBeanAdvisor	测试用。
     │   ├── OrderedTxCheckAdvisor	用于事务检查。
     │   └── NeverMatchAdvisor
     └── JCacheOperationSourcePointcut
关键类与接口的区别说明
ClassFilter vs MethodMatcher
ClassFilter：决定是否对某个类进行拦截。
MethodMatcher：在类匹配后，进一步判断具体的方法是否需要被拦截。
StaticMethodMatcherPointcut vs DynamicMethodMatcherPointcut
前者在编译时即可确定匹配结果，性能更高；后者支持运行时动态判断，灵活性更强。
AspectJExpressionPointcut 支持使用 AspectJ 表达式语言（如 execution(* com.example.service.*.*(..))）定义复杂切入点，是实际开发中最常用的实现之一。
ComposablePointcut 允许组合多个 Pointcut 实例（如通过 and, or, not 操作），构建复合条件。

4. 使用场景
事务管理：通过 TransactionAttributeSourcePointcut 匹配带有 @Transactional 注解的方法。
缓存控制：利用 CacheOperationSourcePointcut 拦截 @Cacheable 等缓存注解的方法。
日志记录：使用 NameMatchMethodPointcut 或正则表达式匹配特定命名的方法进行日志输出。
权限校验：结合自定义 AnnotationMatchingPointcut 拦截带有安全注解的方法。
AOP 编程：配合 Advisor 和 Advice 实现横切关注点（如监控、异常处理等）。

5. 实际代码应用示例
========AnnotationMatchingPointcut 实现了 Pointcut 接口，仅匹配带有 @Loggable 注解的方法，并触发对应的日志增强逻辑。
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Loggable // 自定义注解
    public void createUser(String name) {
        System.out.println("Creating user: " + name);
    }
}

// 定义一个 Pointcut 来匹配带有 @Loggable 注解的方法
Pointcut loggablePointcut = new AnnotationMatchingPointcut(Loggable.class);

// 在配置中使用该 Pointcut
@Bean
public Advisor loggingAdvisor() {
    return new DefaultPointcutAdvisor(loggablePointcut, new LoggingAdvice());
}

 */
public interface Pointcut {

	/**
	 * Return the ClassFilter for this pointcut.
	 * @return the ClassFilter (never {@code null})
	 */
	ClassFilter getClassFilter();

	/**
	 * Return the MethodMatcher for this pointcut.
	 * @return the MethodMatcher (never {@code null})
	 */
	MethodMatcher getMethodMatcher();


	/**
	 * Canonical Pointcut instance that always matches.
	 */
	Pointcut TRUE = TruePointcut.INSTANCE;

}
